package com.carcenter.personnel.controller;

import cn.hutool.core.bean.BeanUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.carcenter.common.dto.ModifyDto;
import com.carcenter.common.pojo.personnel.StaffSearchDto;
import com.carcenter.common.pojo.personnel.StoreManager;
import com.carcenter.common.pojo.store.StoreDto;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.carcenter.common.dto.StaffDto;
import com.carcenter.common.page.MyPageData;
import com.carcenter.common.result.Result;
import com.carcenter.common.result.enums.impl.BusinessCode;
import com.carcenter.common.result.enums.impl.ResultCode;
import com.carcenter.common.vo.StaffVo;
import com.carcenter.personnel.entity.*;
import com.carcenter.personnel.service.IRolesService;
import com.carcenter.personnel.service.IStaffService;
import com.carcenter.personnel.service.IUsersService;
import com.store.client.StoreApi;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.*;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;
import com.carcenter.common.dto.LoginDto;
import com.carcenter.common.dto.RegisterDto;
import com.carcenter.common.result.Result;
import com.carcenter.common.vo.LoginVo;
import com.carcenter.personnel.entity.Staff;
import com.carcenter.personnel.service.IStaffService;
import org.springframework.beans.factory.annotation.Autowired;

import java.util.*;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

/**
 * <p>
 *  前端控制器
 * </p>
 *
 * @author car
 * @since 2025-07-16
 */
@RestController
@RequestMapping("/staff")
public class StaffController {
    @Autowired
    private IStaffService staffService;


    @Autowired
    StoreApi storeApi;


    @Autowired
    IRolesService rolesService;

    //手机号密码登录-dto:手机号、密码     返回： token
    @PostMapping("/login")
    public Result<?> login(@RequestBody LoginDto loginDto){
        LoginVo loginVo =staffService.login(loginDto);
        return Result.ok(loginVo);
    }

    //验证手机号验证码
    @PostMapping("/checkPhone")
    public Result<?> checkPhone(@RequestBody RegisterDto registerDto ){
        staffService.checkPhone(registerDto);
        return Result.ok();
    }

    //注册- dto:手机号、验证码、姓名、密码 、账号、门店  返回：staff
    @PostMapping("/register")
    public Result<?> register(@RequestBody RegisterDto registerDto ){
        Staff staff = staffService.register(registerDto);
        LoginDto loginDto = new LoginDto();
        loginDto.setPhone(registerDto.getPhone());
        loginDto.setLoginPassword(registerDto.getPwd());
        return Result.ok();
    }


    @GetMapping("/getStoreIdsByStaffName")
    public Result getStoreIdsByStaffName(@RequestParam String staffName) {
        List<Integer> storeIds = staffService.lambdaQuery()
                .like(Staff::getStaffName, staffName)
                .select(Staff::getStoreId)
                .list() // 返回 List<Staff>（但只包含 storeId 字段）
                .stream()
                .map(Staff::getStoreId)
                .collect(Collectors.toList());
        return Result.ok(storeIds);
    }


    @PostMapping("/getStoreManagersByManagerIds")
    public Result<List<StoreManager>> getStoreManagersByManagerIds(@RequestBody List<Integer> managerIds){
        List<Staff> staffList = staffService.listByIds(managerIds);
        List<StoreManager> storeManagers = new ArrayList<>();
        for (Staff staff : staffList) {
            StoreManager storeManager = new StoreManager();
            BeanUtils.copyProperties(staff, storeManager);
            storeManagers.add(storeManager);
        }
        return Result.ok(storeManagers);
    }


    @PostMapping("/getStaffListWithSearchDto")
    public Result<List<StaffRolePermitVo>> getStaffListWithSearchDto(@RequestBody(required = false) StaffSearchDto staffSearchDto){
        LambdaQueryWrapper<Staff> queryWrapper = Wrappers.lambdaQuery(Staff.class);

        // 1. 处理门店名称条件（根据门店名查门店ID，避免IN空列表）
        if (staffSearchDto != null && StringUtils.hasText(staffSearchDto.getStoreName())) {

            List<Integer> storeIds=new ArrayList<>();
            // 修正方法名：根据门店名查ID（原方法名可能笔误）
            Result<List<Integer>> idsResult = storeApi.getStoreIdsByStoreName(staffSearchDto.getStoreName());

            if(idsResult!=null&&idsResult.getCode()== ResultCode.SUCCESS.getCode()){
                List<Integer> data1 = idsResult.getData();
                storeIds=data1!=null?data1:new ArrayList<>();
            }

            // 只有当storeIds非空时才添加IN条件（避免SQL语法错误）
            if (storeIds != null && !storeIds.isEmpty()) {
                queryWrapper.in(Staff::getStoreId, storeIds);
            } else {
                // 若门店名存在但无匹配门店，直接返回空列表（避免全表扫描）
                return Result.ok(Collections.emptyList());
            }
        }

        // 2. 处理员工信息条件（姓名/电话模糊查询）
        if (staffSearchDto != null && StringUtils.hasText(staffSearchDto.getStaffInfo())) {
            queryWrapper.and(qw -> qw
                    .like(Staff::getStaffName, staffSearchDto.getStaffInfo())
                    .or()
                    .like(Staff::getPhone, staffSearchDto.getStaffInfo())
            );
        }

        // 3. 查询员工列表（合并原"查询所有"的逻辑）
        List<Staff> list = staffService.list(queryWrapper);

        if (list == null || list.size() <= 0) {
            return Result.ok(Collections.emptyList());
        }


        // 1. 批量查询角色（解决N+1查询）
        // 收集所有非空的roleId
        Set<Integer> roleIds = list.stream()
                .map(Staff::getRoleId)
                .filter(Objects::nonNull)
                .collect(Collectors.toSet());

        // 批量查询角色并转为Map（roleId -> Roles）
        Map<Integer, Roles> roleMap = new HashMap<>();
        if (!roleIds.isEmpty()) {
            List<Roles> roles = rolesService.listByIds(roleIds);
            for (Roles role : roles) {
                roleMap.put(role.getId(), role);
            }
        }

        // 2. 批量查询门店（解决远程调用N+1问题）
        // 收集所有非空的storeId
        Set<Integer> storeIds = list.stream()
                .map(Staff::getStoreId)
                .filter(Objects::nonNull)
                .collect(Collectors.toSet());
        // 批量查询门店（假设storeApi有批量查询接口，若没有则需优化API）
        Map<Integer, StoreDto> storeMap = new HashMap<>();
        if (!storeIds.isEmpty()) {
            List<StoreDto> storeDtos = new ArrayList<>();
            Result<List<StoreDto>> storesResult = storeApi.getStoreDtosByIds(new ArrayList<>(storeIds));
            if (storesResult != null && storesResult.getCode() == ResultCode.SUCCESS.getCode()) {
                storeDtos = Optional.ofNullable(storesResult.getData()).orElse(new ArrayList<>());
            }

            // 直接遍历，无需检查空值
            storeDtos.forEach(store -> storeMap.put(store.getStoreId(), store));
        }

//        if (!storeIds.isEmpty()) {
//            // 假设新增批量查询接口：getStoreDtosByIds（推荐）
//            List<StoreDto> storeDtos=new ArrayList<>();
//            Result<List<StoreDto>> storesResult = storeApi.getStoreDtosByIds(new ArrayList<>(storeIds));
//            if(storesResult!=null&&storesResult.getCode()== ResultCode.SUCCESS.getCode()){
//                List<StoreDto> data2 = storesResult.getData();
//                storeDtos=data2!=null?data2:new ArrayList<>();
//            }
//
//            if (storeDtos != null && !storeDtos.isEmpty()) {
//                for (StoreDto store : storeDtos) {
//                    storeMap.put(store.getStoreId(), store);
//                }
//            }
//        }

        List<StaffRolePermitVo> staffRolePermitVos = new ArrayList<>();
        // 3. 一次性给所有员工设置角色和门店（循环内仅做内存映射，无IO操作）
        for (Staff staff : list) {
            staff.setRole(roleMap.get(staff.getRoleId()));
            staff.setStoreDto(storeMap.get(staff.getStoreId()));
            StaffRolePermitVo staffRolePermitVo = new StaffRolePermitVo();
            BeanUtils.copyProperties(staff, staffRolePermitVo);
            staffRolePermitVos.add(staffRolePermitVo);
        };

        return Result.ok(staffRolePermitVos);
    }

    @PutMapping("/modifyRoleByStaffId/{staffId}/{roleId}")
    public Result<String> modifyRoleByStaffId(@PathVariable Integer staffId,@PathVariable Integer roleId) {
        LambdaUpdateWrapper<Staff> wrapper = Wrappers.lambdaUpdate(Staff.class)
                .eq(Staff::getId, staffId)
                .set(Staff::getRoleId, roleId);
        staffService.update(wrapper);
        return Result.ok(BusinessCode.MODIFY_SUCCESS.getMessage());

    }

    @GetMapping("/getStaffListByStoreId/{storeId}")
    public Result<List<StaffRolePermitVo>> getStaffListByStoreId(@PathVariable Integer storeId){
        LambdaQueryWrapper<Staff> queryWrapper = Wrappers.lambdaQuery(Staff.class)
                .eq(Staff::getStoreId, storeId);
        List<Staff> list = staffService.list(queryWrapper);

        // 1. 批量查询角色（解决N+1查询）
        // 收集所有非空的roleId
        Set<Integer> roleIds = list.stream()
                .map(Staff::getRoleId)
                .filter(Objects::nonNull)
                .collect(Collectors.toSet());

        // 批量查询角色并转为Map（roleId -> Roles）
        Map<Integer, Roles> roleMap = new HashMap<>();
        if (!roleIds.isEmpty()) {
            List<Roles> roles = rolesService.listByIds(roleIds);
            for (Roles role : roles) {
                roleMap.put(role.getId(), role);
            }
        }

        List<StaffRolePermitVo> staffRolePermitVos = new ArrayList<>();
        for (Staff staff : list) {
            StaffRolePermitVo staffRolePermitVo = new StaffRolePermitVo();
            staffRolePermitVo.setRole(roleMap.get(staff.getRoleId()));
            staffRolePermitVo.setStaffName(staff.getStaffName());
            staffRolePermitVo.setPhone(staff.getPhone());
            staffRolePermitVo.setId(staff.getId());
            staffRolePermitVo.setStoreId(staff.getStoreId());

            staffRolePermitVos.add(staffRolePermitVo);
        }
        return Result.ok(staffRolePermitVos);
    }


    //查询员工账号详情-dto:key(员工姓名，员工账号)、账号类型    分页数据
    @PostMapping("/getStaffDetail/{pageNum}/{pageSize}")
    public Result<?> getStaffDetail(@PathVariable("pageNum") Integer pageNum,
                                    @PathVariable("pageSize") Integer pageSize,
                                    @RequestBody(required = false) StaffDto staffDto){
        Page<Staff> page = staffService.getStaffDetail(pageNum,pageSize,staffDto);
        List<Staff> staffs = page.getRecords();

        // 提取 roleId 并查询 roleName
        Map<Integer, String> roleIdToNameMap = rolesService.getRoleNamesByIds(
                staffs.stream()
                        .map(Staff::getRoleId)
                        .distinct()
                        .collect(Collectors.toList())
        );

        // 转换为 StaffVo
        List<StaffVo> staffVoList = staffs.stream()
                .map(staff -> new StaffVo(
                        staff.getId(),
                        staff.getStaffAccount(),
                        staff.getStaffName(),
                        staff.getPhone(),
                        roleIdToNameMap.get(staff.getRoleId())
                ))
                .collect(Collectors.toList());

        return Result.ok(new MyPageData(page.getTotal(), staffVoList));
    }


    //搜索员工-id
    @GetMapping("/getStaffById/{id}")
    public Result<?> getStaffById(@PathVariable("id") Integer id) {
        Staff staff = staffService.getById(id);
        return Result.ok(staff);
    }
    //修改密码
    @PostMapping("/modifyPassword/{id}")
    public Result<?> modifyPassword(@PathVariable("id") Integer id,
                                    @RequestBody ModifyDto modifyDto) {
        staffService.modifyPassword(id,modifyDto);
        return Result.ok(BusinessCode.MODIFY_SUCCESS.getMessage());
    }

    //编辑
    @PutMapping("/update")
    public Result<?> update(@RequestBody Staff staff){
        staffService.updateStaff(staff);
        return Result.ok(BusinessCode.MODIFY_SUCCESS.getMessage());
    }



    //删除员工-id
    @DeleteMapping("/delete/{id}")
    public Result<?> delete(@PathVariable Integer id){
        staffService.removeStaff(id);
        return Result.ok(BusinessCode.REMOVE_SUCCESS.getMessage());
    }
}
